#ifndef __THREAD_SAFE_STACK__
#define __THREAD_SAFE_STACK__

#include "stack.h"

namespace algo
{


template<typename T>
class ThreadSafeStack
{
public:
	ThreadSafeStack() {}

	ThreadSafeStack & operator=(const ThreadSafeStack&) = delete;

	void push(T val)
	{
		std::lock_guard<std::mutex> lock(m_mutex);
		m_data.push(std::move(val));
	}

	std::shared_ptr<T> pop()
	{
		std::lock_guard<std::mutex> lock(m_mutex);
		if (isEmpty())
			throw empty_stack();
		const std::shared_ptr<T> res(std::make_shared<T>(std::move(m_data.top())));
		m_data.pop();
		return res;

	}

	bool isEmpty()
	{
		std::lock_guard<std::mutex> lock(m_mutex);
		return m_data.isEmpty();
	}

private:
	Stack<T> m_data;
	mutable std::mutex m_mutex;

};

}	// namespace end

#endif

